package com.xyy.saas.payment.util.mq;

import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.adpater.yzh.constant.ConfigPath;
import com.xyy.saas.payment.adpater.yzh.constant.DataDict;
import com.xyy.saas.payment.adpater.yzh.util.HttpUtil;
import com.xyy.saas.payment.adpater.yzh.util.YzhResultParseUtil;
import com.xyy.saas.payment.adpater.yzh.vo.BankCardOrder;
import com.xyy.saas.payment.adpater.yzh.vo.BankCardOrderResp;
import com.xyy.saas.payment.common.RocketMqGroup;
import com.xyy.saas.payment.common.RocketMqTopic;
import com.xyy.saas.payment.cores.enums.BankPayStatusEnum;
import com.xyy.saas.payment.dao.model.BankPayRecord;
import com.xyy.saas.payment.manager.BankPayManager;
import com.xyy.saas.payment.service.BankPayRecordService;
import com.xyy.saas.payment.util.ApolloUtil;
import com.xyy.saas.payment.util.JSONUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @Author lina
 * @Description 银行卡转账处理
 * @Date 2022/3/9
 **/
@Service
@RocketMQMessageListener(topic = RocketMqTopic.TOPIC_ASYNC_BANK_PAY, consumerGroup = RocketMqGroup.GROUP_BANK_PAY_CONSUMER, consumeMode = ConsumeMode.ORDERLY)
public class BankPayConsumer implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(BankPayConsumer.class);

    @Autowired
    private BankPayManager bankPayManager;
    @Autowired
    private BankPayRecordService bankPayRecordService;

    @Override
    public void onMessage(MessageExt messageExt) {
        LOGGER.info("BankPayConsumer MQ receive message body:{}.", messageExt.getBody());
        String payNo = new String(messageExt.getBody());
        if (StringUtils.isBlank(payNo)){
            LOGGER.error("BankPayConsumer MQ receive message fail payNo is blank.");
            return;
        }
        //1:校验数据
        BankPayRecord bankPayRecord = bankPayRecordService.queryByPayNo(payNo);
        if(null == bankPayRecord) {
            LOGGER.error("BankPayConsumer query bankPayRecord is not exist. payNo:{}", payNo);
            return;
        }
        LOGGER.info("BankPayConsumer query bankPayRecord:{}", JSONUtils.toJSON(bankPayRecord));
        //2:校验状态
        if (BankPayStatusEnum.fromCode(bankPayRecord.getStatus()) != BankPayStatusEnum.RECEIVED) {
            LOGGER.warn("BankPayConsumer bankPayRecord status is not received status");
            return;
        }
        //3:请求云账户-银行卡支付
        BankCardOrder bankCardOrder = BankPayManager.buildBankCardOrder(bankPayRecord);
        Map<String, Object> result = null;
        BankPayStatusEnum updateStatus = BankPayStatusEnum.DEALING;
        try {
            LOGGER.info("BankPayConsumer bankPayRecord request yzh# param:{}", JSONUtils.toJSON(bankCardOrder));
            result = HttpUtil.post(bankCardOrder.assembleRequest(ConfigPath.HY_BANK_PAY), ApolloUtil.getProperty(ConfigPath.YZH_BANK_CARD_REAL_TIME_ORDER));
        } catch (Exception e) {
            LOGGER.error("BankPayConsumer bankPayRecord request yzh异常# param:{}", JSONUtils.toJSON(bankCardOrder), e);
        }
        LOGGER.info("BankPayConsumer bankPayRecord request yzh# result:{}", null != result ? JSONUtils.toJSON(result) : null);
        //同步调用云账户结果 默认成功
        //失败原因
        String failMsg = null;
        String yzhCode = null;
        //4::解析返回值
        BankCardOrderResp bankCardOrderResp = getResultDataFromResult(result);
        String refNo = null;
        if (null != bankCardOrderResp) {
            refNo = bankCardOrderResp.getRef();
            updateStatus = DataDict.SUCCESS_CODE.equals(bankCardOrderResp.getCode()) ? BankPayStatusEnum.DEALING : BankPayStatusEnum.FAIL;
            failMsg = bankCardOrderResp.getFailMsg();
            yzhCode = bankCardOrderResp.getCode();
        }
        if (null == bankCardOrderResp) {
            updateStatus = BankPayStatusEnum.FAIL;
            failMsg = "系统错误";
        }
        //4:转账记录改为 处理中
        boolean updateResult = bankPayManager.updateBankPayStatus(payNo, updateStatus, refNo, failMsg);
        if (!updateResult) {
            LOGGER.error("BankPayConsumer update status error. payNo:{}, status:{}", payNo, updateStatus);
            return;
        }
        //5：回调
        bankPayManager.bankPayCallback(updateStatus.getStatus(), bankPayRecord, yzhCode, LocalDateTime.now());
        LOGGER.info("BankPayConsumer#onMessage apply_bank_pay end bankCardOrder:{}", JSON.toJSON(bankCardOrder));
    }

    private static BankCardOrderResp getResultDataFromResult(Map<String, Object> result) {
        return YzhResultParseUtil.parseBankPayApplyResult(result);
    }

    @Override
    public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
        defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        defaultMQPushConsumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
    }
}
